package com.mhr.ai.cr.toolWindow

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.ui.JBSplitter
import com.intellij.ui.components.*
import com.intellij.ui.table.JBTable
import com.intellij.util.ui.JBUI
import com.mhr.ai.cr.GitMRBundle
import com.mhr.ai.cr.model.ChangeType
import com.mhr.ai.cr.model.FileChange
import com.mhr.ai.cr.model.GitMRInfo
import com.mhr.ai.cr.service.GitMRService
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.FlowLayout
import java.awt.Font
import java.util.concurrent.CompletableFuture
import javax.swing.*
import javax.swing.table.DefaultTableModel

/**
 * Git MR 分析工具窗口
 */
class GitMRToolWindow(private val project: Project) {
    
    private val logger = thisLogger()
    private val gitMRService = project.service<GitMRService>()
    
    // 保存当前的变更列表，用于显示差异
    private var currentChanges: List<FileChange> = emptyList()
    
    // UI 组件
    private val urlTextField = JBTextField().apply {
        toolTipText = "输入 GitLab/GitHub MR/PR 链接"
    }
    
    private val analyzeButton = JButton("分析 MR").apply {
        toolTipText = "分析指定的 Merge Request"
    }
    
    private val statusLabel = JBLabel("就绪")
    
    private val mrInfoPanel = JBPanel<JBPanel<*>>(BorderLayout()).apply {
        border = JBUI.Borders.empty(10)
        isVisible = false
    }
    
    private val fileChangesTable = JBTable().apply {
        fillsViewportHeight = true
        setShowGrid(true)
    }
    
    private val diffTextArea = JBTextArea().apply {
        isEditable = false
        font = Font(Font.MONOSPACED, Font.PLAIN, 12)
        lineWrap = false
    }
    
    /**
     * 创建工具窗口内容
     */
    fun getContent(): JComponent {
        return JBPanel<JBPanel<*>>(BorderLayout()).apply {
            // 顶部输入区域
            add(createInputPanel(), BorderLayout.NORTH)
            
            // 中间分割面板
            add(createMainPanel(), BorderLayout.CENTER)
            
            // 底部状态栏
            add(createStatusPanel(), BorderLayout.SOUTH)
        }
    }
    
    /**
     * 创建输入面板
     */
    private fun createInputPanel(): JComponent {
        return JBPanel<JBPanel<*>>(BorderLayout()).apply {
            border = JBUI.Borders.empty(10)
            
            add(JBLabel("MR 链接:"), BorderLayout.WEST)
            add(urlTextField, BorderLayout.CENTER)
            
            val buttonPanel = JBPanel<JBPanel<*>>(FlowLayout(FlowLayout.RIGHT)).apply {
                add(analyzeButton)
            }
            add(buttonPanel, BorderLayout.EAST)
        }
    }
    
    /**
     * 创建主面板
     */
    private fun createMainPanel(): JComponent {
        val splitPane = JBSplitter(true, 0.4f)
        splitPane.firstComponent = createMRInfoPanel()
        splitPane.secondComponent = createFileChangesPanel()
        
        return splitPane
    }
    
    /**
     * 创建 MR 信息面板
     */
    private fun createMRInfoPanel(): JComponent {
        return JBScrollPane(mrInfoPanel).apply {
            preferredSize = Dimension(0, 200)
        }
    }
    
    /**
     * 创建文件变更面板
     */
    private fun createFileChangesPanel(): JComponent {
        val splitPane = JBSplitter(false, 0.5f)
        splitPane.firstComponent = JBScrollPane(fileChangesTable).apply {
            preferredSize = Dimension(300, 0)
        }
        splitPane.secondComponent = JBScrollPane(diffTextArea)
        
        return splitPane
    }
    
    /**
     * 创建状态面板
     */
    private fun createStatusPanel(): JComponent {
        return JBPanel<JBPanel<*>>(FlowLayout(FlowLayout.LEFT)).apply {
            border = JBUI.Borders.empty(5, 10)
            add(JBLabel("状态: "))
            add(statusLabel)
        }
    }
    
    init {
        setupEventHandlers()
    }
    
    /**
     * 设置事件处理器
     */
    private fun setupEventHandlers() {
        // 分析按钮点击事件
        analyzeButton.addActionListener {
            analyzeMergeRequest()
        }
        
        // URL 输入框回车事件
        urlTextField.addActionListener {
            analyzeMergeRequest()
        }
        
        // 文件变更表格选择事件
        fileChangesTable.selectionModel.addListSelectionListener { e ->
            if (!e.valueIsAdjusting) {
                val selectedRow = fileChangesTable.selectedRow
                if (selectedRow >= 0) {
                    showFileDiff(selectedRow)
                }
            }
        }
    }
    
    /**
     * 分析 Merge Request
     */
    private fun analyzeMergeRequest() {
        val mrUrl = urlTextField.text.trim()
        if (mrUrl.isEmpty()) {
            Messages.showWarningDialog(project, "请输入 MR 链接", "警告")
            return
        }
        
        analyzeButton.isEnabled = false
        statusLabel.text = "正在分析 MR..."
        
        // 使用 CompletableFuture 替代协程
        CompletableFuture.supplyAsync {
            try {
                gitMRService.analyzeMRUrl(mrUrl)
            } catch (e: Exception) {
                Result.failure<GitMRInfo>(e)
            }
        }.thenAccept { result ->
            SwingUtilities.invokeLater {
                result.fold(
                    onSuccess = { mrInfo ->
                        displayMRInfo(mrInfo)
                        statusLabel.text = "分析完成 - 共 ${mrInfo.changes.size} 个变更"
                    },
                    onFailure = { error ->
                        Messages.showErrorDialog(
                            project,
                            "分析失败: ${error.message}",
                            "错误"
                        )
                        statusLabel.text = "分析失败"
                    }
                )
                analyzeButton.isEnabled = true
            }
        }.exceptionally { throwable ->
            SwingUtilities.invokeLater {
                Messages.showErrorDialog(
                    project,
                    "分析过程中发生错误: ${throwable.message}",
                    "错误"
                )
                statusLabel.text = "分析失败"
                analyzeButton.isEnabled = true
            }
            null
        }
    }
    
    /**
     * 显示 MR 信息
     */
    private fun displayMRInfo(mrInfo: GitMRInfo) {
        // 保存当前变更列表
        currentChanges = mrInfo.changes
        
        // 更新 MR 基本信息
        mrInfoPanel.removeAll()
        mrInfoPanel.add(createMRInfoContent(mrInfo), BorderLayout.CENTER)
        mrInfoPanel.isVisible = true
        
        // 更新文件变更表格
        updateFileChangesTable(mrInfo.changes)
        
        // 清空差异显示
        diffTextArea.text = "请选择一个文件查看差异"
        
        mrInfoPanel.revalidate()
        mrInfoPanel.repaint()
    }
    
    /**
     * 创建 MR 信息内容
     */
    private fun createMRInfoContent(mrInfo: GitMRInfo): JComponent {
        return JBPanel<JBPanel<*>>().apply {
            layout = BoxLayout(this, BoxLayout.Y_AXIS)
            border = JBUI.Borders.empty(10)
            
            add(JBLabel("<html><h3>${mrInfo.title}</h3></html>"))
            add(Box.createVerticalStrut(5))
            add(JBLabel("作者: ${mrInfo.author}"))
            add(JBLabel("源分支: ${mrInfo.sourceBranch} → 目标分支: ${mrInfo.targetBranch}"))
            add(Box.createVerticalStrut(5))
            add(JBLabel("描述: ${mrInfo.description}"))
            add(Box.createVerticalStrut(10))
            
            // 变更统计
            add(JBLabel("<html><b>变更统计:</b></html>"))
            add(JBLabel("• 总变更: ${mrInfo.changes.size} 个文件"))
            
            val addedFiles = mrInfo.changes.count { it.changeType == ChangeType.ADDED }
            val modifiedFiles = mrInfo.changes.count { it.changeType == ChangeType.MODIFIED }
            val deletedFiles = mrInfo.changes.count { it.changeType == ChangeType.DELETED }
            val totalAdditions = mrInfo.changes.sumOf { it.addedLines }
            val totalDeletions = mrInfo.changes.sumOf { it.removedLines }
            
            add(JBLabel("• 新增: $addedFiles 个文件"))
            add(JBLabel("• 修改: $modifiedFiles 个文件"))
            add(JBLabel("• 删除: $deletedFiles 个文件"))
            add(JBLabel("• 总计: +$totalAdditions -$totalDeletions 行"))
        }
    }
    
    /**
     * 更新文件变更表格
     */
    private fun updateFileChangesTable(changes: List<FileChange>) {
        val columnNames = arrayOf(
            "文件路径",
            "变更类型", 
            "添加行数",
            "删除行数"
        )
        
        val data = changes.map { change ->
            arrayOf(
                change.newPath,
                getChangeTypeText(change.changeType),
                change.addedLines.toString(),
                change.removedLines.toString()
            )
        }.toTypedArray()
        
        val model = DefaultTableModel(data, columnNames)
        fileChangesTable.model = model
        
        // 设置列宽
        if (fileChangesTable.columnModel.columnCount > 0) {
            fileChangesTable.columnModel.getColumn(0).preferredWidth = 200
            fileChangesTable.columnModel.getColumn(1).preferredWidth = 80
            fileChangesTable.columnModel.getColumn(2).preferredWidth = 60
            fileChangesTable.columnModel.getColumn(3).preferredWidth = 60
        }
    }
    
    /**
     * 获取变更类型文本
     */
    private fun getChangeTypeText(changeType: ChangeType): String {
        return when (changeType) {
            ChangeType.ADDED -> "新增"
            ChangeType.MODIFIED -> "修改"
            ChangeType.DELETED -> "删除"
            ChangeType.RENAMED -> "重命名"
        }
    }
    
    /**
     * 显示文件差异
     */
    private fun showFileDiff(selectedRow: Int) {
        if (selectedRow < 0 || selectedRow >= currentChanges.size) {
            return
        }
        
        val fileChange = currentChanges[selectedRow]
        val fileName = fileChange.newPath
        val changeType = getChangeTypeText(fileChange.changeType)
        
        val diffContent = StringBuilder()
        diffContent.appendLine("文件: $fileName")
        diffContent.appendLine("变更类型: $changeType")
        diffContent.appendLine("添加行数: ${fileChange.addedLines}")
        diffContent.appendLine("删除行数: ${fileChange.removedLines}")
        diffContent.appendLine()
        diffContent.appendLine("差异内容:")
        diffContent.appendLine("=".repeat(50))
        diffContent.append(fileChange.diff)
        
        diffTextArea.text = diffContent.toString()
        diffTextArea.caretPosition = 0
    }
}